#include "sport.h"

static uint8_t _rx_buf[64+3];
static uint8_t _tx_buf[64+3];
static uint8_t _rx_buf_pos=0;
uint8_t sport_or_crsf_flag = 0; //0:sport 1:crsf
uint8_t _tx_buf_pos = 0;
uint8_t Sport_State = 0;
uint32_t Sprot_last_recv_time=0;
extern uint8_t crsf_flag;
void  CRSF_handle_uart_in(void)
{
//		uint8_t num = 0;
//		num = LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_5);
		sport_or_crsf_flag  = LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_5);
			LL_USART_Enable(USART1);
			LL_USART_Enable(USART2);
    if(sport_or_crsf_flag)
    {
			LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_7, LL_GPIO_MODE_INPUT);
			LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_7, LL_GPIO_PULL_NO);  // 不启用上下拉电阻
			// 配置 GPIOB 7 引脚为输入模式（RX 引脚）
			LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_3, LL_GPIO_MODE_INPUT);
			LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_3, LL_GPIO_PULL_NO);  // 不启用上下拉电阻
			//sport
        while(uart1_read_buf_len())
        {
            _rx_buf[_rx_buf_pos] = uart1_read_byte();
            _rx_buf_pos++;
            CRSF_handle_byte_received();
        }
					//_tx_buf
				if(crsf_flag == 1)
				{
					crsf_flag = 0;
					sendCRSFFrame(_tx_buf);
					LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_3, (uint32_t)_rx_buf);
				}
    }
    else if (!sport_or_crsf_flag)
    {
				LL_USART_Enable(USART1);
							// 配置 GPIOB 6 引脚为复用模式（TX 引脚恢复为 USART1_TX）
//				LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_7, LL_GPIO_MODE_ALTERNATE);
//				LL_GPIO_SetAFPin_0_7(GPIOB, LL_GPIO_PIN_7, LL_GPIO_AF_7);  // 配置为 USART1_TX 的复用功能
				// 启用 USART1 外设

        while(uart2_read_buf_len())
        {
						_rx_buf[_rx_buf_pos] = uart2_read_byte();
						_rx_buf_pos++;
						CRSF_handle_byte_received();
        }
					//_tx_buf
				if(crsf_flag == 1)
				{
					crsf_flag = 0;
					sendCRSFFrame(_tx_buf);
					LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)_rx_buf);
				}
    }

		uint32_t now = millis();
    if(now > Sprot_last_recv_time && (now - Sprot_last_recv_time) > 1000)
    {
        Sport_State = SPORT_DISCONNECT;
    }
	
}

// Shift the bytes in the RxBuf down by cnt bytes
void shift_rx_buffer(uint8_t cnt)
{
    // If removing the whole thing, just set pos to 0
    if (cnt >= _rx_buf_pos)
    {
        _rx_buf_pos = 0;
        return;
    }

    // Otherwise do the slow shift down
    uint8_t *src = &_rx_buf[cnt];
    uint8_t *dst = &_rx_buf[0];
    _rx_buf_pos -= cnt;
    uint8_t left = _rx_buf_pos;
    while (left--)
        *dst++ = *src++;
}

void CRSF_handle_byte_received()
{
    uint8_t reprocess;
    do
    {
        reprocess = 0;
        if (_rx_buf_pos > 1)
        {
            uint8_t len = _rx_buf[1];
            // Sanity check the declared length, can't be shorter than Type, X, CRC
            if (len < 3 || len > CRSF_MAX_PACKET_LEN)
            {
                shift_rx_buffer(1);
                reprocess = 1;
            }
            else if (_rx_buf_pos >= (len + 2))
            {
                uint8_t inCrc = _rx_buf[2 + len - 1];
                uint8_t crc = calculate_crc8_from_table(&_rx_buf[2], len - 1);
                if (crc == inCrc)
                {
										memcpy(_tx_buf,_rx_buf,len + 2);
                    shift_rx_buffer(len + 2);
									  Sprot_last_recv_time = millis();
										Sport_State = SPORT_CONNETED;
                    reprocess = 1;
                }
                else
                {
                    shift_rx_buffer(1);
                    reprocess = 1;
                }
            }  // if complete packet
        } // if pos > 1
    } while (reprocess);
}

uint8_t SPORT_get_state(void)
{
    return Sport_State;
}

